import asyncio
import re
from typing import Any

from app.bot.utils.kopeechka.errors import WAIT_LINK
from app.bot.utils.kopeechka.schemas import MailboxGetEmail, MailboxGetMessage
from app.bot.utils.kopeechka.utils import request_get
from app.bot.utils.logger import log


class AsyncKopeechka:
    def __init__(
        self,
        token: str,
    ) -> None:
        self.token = token

    async def mailbox_get_email(
        self,
        site: str = None,
        mail_type: str = None,
        sender: str = None,
        regex: str = None,
        soft_id: int = None,
        investor: int = None,
        subject: str = None,
        clear: int = None,
    ) -> MailboxGetEmail:
        query = {
            "site": site,
            "mail_type": mail_type,
            "token": self.token,
            "sender": sender,
            "regex": regex,
            "soft_id": soft_id,
            "investor": investor,
            "subject": subject,
            "clear": clear,
            "type": "json",
            "api": 2.0,
        }
        return await request_get(
            url="http://api.kopeechka.store/mailbox-get-email",
            params=query,
            type_kopeechka=MailboxGetEmail,
        )

    async def mailbox_get_message(
        self, full: int = None, email_id: int = None
    ) -> MailboxGetMessage:
        query = {
            "full": full,
            "id": email_id,
            "token": self.token,
            "type": "json",
            "api": 2.0,
        }
        return await request_get(
            url="http://api.kopeechka.store/mailbox-get-message",
            params=query,
            type_kopeechka=MailboxGetMessage,
        )

    async def get_code_from_mail(
        self, full: int = None, email_id: int = None
    ) -> bool | Any:
        """Получаем код с копеечки"""

        retries = 0
        log.info("Жду код с почты копечки")
        while True:
            try:
                message = await self.mailbox_get_message(full, email_id)
            except WAIT_LINK:
                retries += 1
                if retries > 10:
                    log.error(f"Не смог получить код после {retries} попыток")
                    return False
                await asyncio.sleep(5)
                continue

            letter_body = message.fullmessage.replace(" ", "")
            code_result = re.findall(r"(\d{6,})", letter_body)
            if len(code_result) > 0:
                log.info(f"Получен код {code_result}")
                return code_result[0]

            return False
